package de.hsma.srn.controller;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import de.hsma.srn.interfaces.Controller;
import de.hsma.srn.model.account.DomainModel;
import de.hsma.srn.model.key.KeyPackageModel;
import de.hsma.srn.model.key.MasterKeyPackageModel;
import de.hsma.srn.model.user.UserModel;


public class KeyBoxController extends Controller {
	private DomainModel mDomain;
	
	/*
	 * Getter & Setter (VIEW CODER SEE HERE)
	 */
	/**
	 * A list of my own keys
	 * @return string list of my own keys
	 */
	public String[] getOwnKeys() {
		List<String> listKeys = new ArrayList<String>();
		for(KeyPackageModel keyPackage : this.mDomain.getAccountModel().getUser().getKeyBox().getOwnKeys()) {
			listKeys.add(keyPackage.getFilePath());
		}
		return listKeys.toArray(new String[0]);
	}
	/**
	 * A list of my assigned keys
	 * @return string list of my assigned keys
	 */
	public String[] getAssignedKeys() {
		List<String> listKeys = new ArrayList<String>();
		for(KeyPackageModel keyPackage : this.mDomain.getAccountModel().getUser().getKeyBox().getAssignedKeys()) {
			listKeys.add(keyPackage.getFilePath());
		}
		return listKeys.toArray(new String[0]);
	}
	/**
	 * Return path to the home directory of the current user
	 * @return
	 */
	public String getHomePath() {
		return this.mDomain.getAccountModel().getUser().getHomePath();
	}
	/**
	 * Return all files in the home directory
	 * @return List of all files in the home directory
	 */
	public String[] getFileList() {
		File homeDirectory = new File(this.getHomePath());
		if(homeDirectory.exists() && homeDirectory.isDirectory()) {
			List<String> listFiles = new ArrayList<String>();
			for(File file : homeDirectory.listFiles()) {
				if( !file.getName().equalsIgnoreCase("profile")
						&& !file.getName().equalsIgnoreCase("keybox")
						&& !file.isHidden()) {
					listFiles.add(file.getName());
				}
			}
			return listFiles.toArray(new String[0]);
		}
		return null;
	}
	/**
	 * Get the username of the current logged in user
	 * @return username
	 */
	public String getUsername() {
		return this.mDomain.getAccountModel().getUserName();
	}
	/**
	 * Return an string array of all users names (except my own)
	 * @return list of all the other user names
	 */
	public String[] getAllUsernames() {
		List<String> userList = new ArrayList<String>();
		String userName;
		for(UserModel user : this.mDomain.getUserList()) {
			userName = user.getUserName();
			if(!userName.equalsIgnoreCase(this.mDomain.getAccountModel().getUserName())) {
				userList.add(user.getUserName());
			}
		}
		return userList.toArray(new String[0]);
	}
	/**
	 * Get a list of all users the given key package with given filename is shared with!
	 * @param filename
	 * @return
	 */
	public String[] getSharedUsersOfKey(String filename) {
		List<String> sharedUsersList = new ArrayList<String>();
		// Find the key
		MasterKeyPackageModel keyPackage = this.getOwnKey(filename);
		if(keyPackage!=null) {
			// key exists, so iterate over all the shared users
			for(UserModel user : keyPackage.getSharedUsers()) {
				sharedUsersList.add(user.getUserName());
			}
		}
		return sharedUsersList.toArray(new String[0]);
	}
	
	private MasterKeyPackageModel getOwnKey(String filename) {
		for(MasterKeyPackageModel keyPackage : this.mDomain.getAccountModel().getUser().getKeyBox().getOwnKeys()) {
			if(keyPackage.getFilePath().equalsIgnoreCase(filename)) {
				return keyPackage;
			}
		}
		return null;
	}
	
	/*
	 * Constructors
	 */
	public KeyBoxController(DomainModel domain) {
		this.mDomain = domain;
	}
	
	
	/*
	 * Methods (VIEW CODER SEE HERE)
	 */
	/**
	 * Create a new key package with the given filepath.
	 * Notice that the source file will be replaced by the encoded one!
	 * @param filename of source file
	 */
	public void createKey(String filepath) {
		File sourceFile = new File(filepath);
		if(sourceFile.exists()) {
			this.mDomain.getAccountModel().getUser().encrypt(sourceFile.getPath(), null);
		}
		this.notifyListeners(mDomain);
	}
	/**
	 * Share the key with given file path if its an OWN master key package to the given users with userNames
	 * @param filepath of the key to be shared
	 * @param userNames of users to share the key with
	 */
	public void shareKey(String filepath, String[] userNames) {
		for(MasterKeyPackageModel keyPackage : this.mDomain.getAccountModel().getUser().getKeyBox().getOwnKeys()) {
			if(keyPackage.getFilePath().equalsIgnoreCase(filepath)) {
				List<UserModel> userList = new ArrayList<UserModel>();
				UserModel user;
				for(String userName : userNames) {
					user = this.mDomain.getUserList().get(userName);
					if(user!=null) {
						userList.add(user);
					}
				}
//				if(!userList.isEmpty()) {
//					this.mDomain.getAccountModel().getUser().share(keyPackage, userList, this.mDomain.getAccountModel().getPassword());
//				}
				this.mDomain.getAccountModel().getUser().share(keyPackage, userList, this.mDomain.getAccountModel().getPassword());		
			}
		}
	}
	/**
	 * Use the key package with the given filename
	 * @param filename of key package
	 */
	public void useKey(String filepath) {
		// TODO: Delete only foreign kes, but not the own master key packages
		System.out.println("Entschluessele " + filepath);
		File sourceFile = new File(filepath);
		if(sourceFile.exists()) {
			File targetFile = new File(this.getHomePath() + "/" + sourceFile.getName());
			if(targetFile.getPath().equalsIgnoreCase(sourceFile.getPath())) {
				System.out.println("File exists!");
				// File already exisits or the encrypted is also my own file
				targetFile = new File(this.getHomePath() + "/decrypted" + sourceFile.getName());
			}
			KeyPackageModel keyPackage = this.mDomain.getAccountModel().getUser().getKeyBox().get(sourceFile.getPath());
			if(this.mDomain.getAccountModel().getUser().decrypt(keyPackage, this.mDomain.getAccountModel().getPassword(), targetFile.getPath())) {
				// Only remove a foreign Key package
				if(!(keyPackage instanceof MasterKeyPackageModel)) {
					//this.mDomain.getAccountModel().getUser().getKeyBox().remove(keyPackage);
				}
				this.notifyListeners(this.mDomain);
			}
		}
	}
	/**
	 * Delete the key with the given filename
	 * @param filename
	 */
	public void deleteKey(String filename) {
		KeyPackageModel keyPackage = this.mDomain.getAccountModel().getUser().getKeyBox().get(filename);
		if(keyPackage!=null) {
			this.mDomain.getAccountModel().getUser().getKeyBox().remove(keyPackage);
			this.notifyListeners(this.mDomain);
		}
	}
	/**
	 * Logout the user
	 */
	public void logout() {
		this.mDomain.logout();
	}
}
